package ModelLayer;
import java.util.ArrayList;


/**
 * Write a description of class Stock here.
 * Description:
 * Collection containing all of the products including
 * KithchenBatchroom products, their data and fields.
 * @author (Georgi Georgiev) 
 * @version (09.12.2013)
 */
public class Stock
{
    private static ArrayList<Product> stock;  
    private static FileStock file;
    private static Stock instance;
    /**
     * Constructor for objects of class Stock
     */
    public Stock()
    {
        file = new FileStock();
        stock = file.get_data();
    }
    
    public static Stock get_instance()
    {
        return instance;
    }
    
    public static void initialize()
    {
        if(instance == null)
        {
            instance = new Stock();
        }
    }
    
    /**********************************************************************************CREATING PRODUCT**********************************************************************************************/
    
    /**
     * Method to add product in the stock collection
     */
    public static boolean add_product(String name, String category, String department, double price, double price_for_palette, int pieces_in_palette, int quantity, int  maximum_amount, int minimum_amount, int amount_qualified_for_discount, String group_nr, double discount)
    {
        int max_temp_art_nr = 0;
        int temp_art_nr = 0;
        String art_nr;
         for (Product articule : stock)
        {
            temp_art_nr = Integer.parseInt(articule.get_art_nr());
            if(max_temp_art_nr < temp_art_nr)
            {
                if(max_temp_art_nr < (temp_art_nr - 1))
                {
                    if(!(does_such_product_exist(art_nr = "" + (max_temp_art_nr + 1))))
                    {
                        break;
                    }
                }
                max_temp_art_nr = temp_art_nr;     
            }
        }
        art_nr = "" + (max_temp_art_nr + 1);         
        stock.add(max_temp_art_nr, new Product(art_nr, name, category, department, price, price_for_palette, pieces_in_palette, quantity, maximum_amount, minimum_amount, amount_qualified_for_discount, group_nr, discount));
        return true;
    }
    
    /**********************************************************************************FINDING(READING) PRODUCT**********************************************************************************************/
    
    /**
     * Method to find product by the articule number in the warehouse(stock)
     */
    public static Product find_product_by_art_nr(String i_art_nr)
    {
        for(Product articule : stock) 
        {
            if(articule.get_art_nr().equals(i_art_nr)) 
            {
                return articule;
            }
        }
        return null;
    }
    
    /**
     * Method to find product by it's the name in the warehouse(stock)
     */
    public static Product find_product_by_name(String i_name)
    {
        for(Product articule : stock) 
        {
            if(articule.get_name().equals(i_name)) 
            {
                return articule;
            }
        }
        return null;
    }
    
    public static String get_art_nr_via_name(String name)
    {
        return find_product_by_name(name).get_art_nr();
    }
    
    /**
     * Method to find products by one cetegory.
     */
    public static ArrayList<Product> find_products_by_category(String i_category)
    {
        ArrayList<Product> var = new ArrayList<>();
        for(Product articule : stock) 
        {
            if(articule.get_category().equals(i_category) && !(articule.is_unfinished())) 
            {
                var.add(articule);
            }
        }
        return var;
    }    
    
    /**
     * Method to check whether a product with such articule number exists
     */
    public static boolean does_such_product_exist(String i_art_nr)
    {
        for(Product articule : stock) 
        {
            if(articule.get_art_nr().equals(i_art_nr)) 
            {
                return true;
            }
        }
        return false;
    }
    
    public static boolean is_such_name(String i_name)
    {
        for(Product articule : stock) 
        {
            if(articule.get_name().equals(i_name)) 
            {
                return true;
            }
        }
        return false;
    }
    
    public static String display_by_group_nr(String group_nr)
    {
        String all_data = "";
        for(Product articule : stock)
        {
            if(articule.get_group_nr().equals(group_nr))
            {
                all_data += articule.printable() + "\n";
            }
        }
        return all_data;
    }
    
    public static String display_unfinished_products()
    {
        String all_data = "";
        for(Product articule : stock)
        {
            if(articule.get_price() == 0)
            {
                all_data += articule.printable() + "\n";
            }
        }
        return all_data;
    }
    
    public static String display_products_that_need_restocking()
    {
        String all_data = "";
        for(Product articule : stock)
        {
            if(articule.needs_restocking() && !(articule.is_unfinished()))
            {
                all_data += articule.restocking_printable() + "\n";
            }
        }
        return all_data;
    }
    
    
    public static boolean is_kitchen_bathroom_product(String art_nr)
    {
        return find_product_by_art_nr(art_nr).get_department().equals("KB");
    }
    
    /**********************************************************************************CHANGING(UPDATE) PRODUCT**********************************************************************************************/
    
    /**
     * Method to change the product's name.
     */
    public static void edit_name(String art_nr, String name)
    {
        find_product_by_art_nr(art_nr).set_name(name);
    }
    
    /**
     * Method to change the product's category.
     */
    public static void edit_category(String art_nr, String category)
    {
        find_product_by_art_nr(art_nr).set_category(category);
    }
    
    /**
     * Method to change the product's department.
     */
    public static void edit_department(String art_nr, String department)
    {
        find_product_by_art_nr(art_nr).set_department(department);
    }
    
    /**
     * Method to change the product's price.
     */
    public static boolean edit_price(String art_nr, double price)
    {
        Product temp = find_product_by_art_nr(art_nr);
        double price_for_palette = temp.get_price_for_palette();
        if(price_for_palette > price || price_for_palette == 0)
        {
            temp.set_price(price);
            return true;
        }
        return false;
    }
    
    /**
     * Method to change the product's price for palette.
     */
    public static boolean edit_price_for_palette(String art_nr, double price_for_palette)
    {
        Product temp = find_product_by_art_nr(art_nr);
        if(temp.get_price() < price_for_palette)
        {
            temp.set_price_for_palette(price_for_palette);
            return true;
        }
        return false;
    }
    
    /**
     * Method to change the product's amount(pieces) in a single palette.
     */
    public static boolean edit_pieces_in_palette(String art_nr, int pieces_in_palette)
    {
        Product temp = find_product_by_art_nr(art_nr);
        if(temp.get_maximum_amount() > pieces_in_palette)
        {
            temp.set_pieces_in_palette(pieces_in_palette);
            return true;
        }
        return false;
    }
    
    /**
     * Method to change the product's quantity.
     */
    public static boolean edit_quantity(String art_nr, int quantity)
    {
        find_product_by_art_nr(art_nr).set_quantity(quantity);
        Product temp = find_product_by_art_nr(art_nr);
        if(temp.get_maximum_amount() > quantity)
        {
            temp.set_quantity(quantity);
            return true;
        }
        return false;
    }
    
    /**
     * Method to change the maximum amount of the product in stock(warehouse).
     */
    public static boolean edit_maximum_amount(String art_nr, int maximum_amount)
    {
        Product temp = find_product_by_art_nr(art_nr);
        if(temp.get_minimum_amount() < maximum_amount)
        {
            temp.set_maximum_amount(maximum_amount);
            return true;
        }
        return false;
    }
    
    /**
     * Method to change the minimum amount of the product in stock(warehouse).
     */
    public static boolean edit_minimum_amount(String art_nr, int minimum_amount)
    {
        Product temp = find_product_by_art_nr(art_nr);
        if(temp.get_maximum_amount() > minimum_amount)
        {
            temp.set_minimum_amount(minimum_amount);
            return true;
        }
        return false;
    }
    
    /**
     * Method to change the minimum amount of the product in stock(warehouse).
     */
    public static boolean edit_amount_qualified_for_discount(String art_nr, int amount_qualified_for_discount)
    {
        Product temp = find_product_by_art_nr(art_nr);
        if(temp.get_maximum_amount() > amount_qualified_for_discount)
        {
            temp.set_amount_qualified_for_discount(amount_qualified_for_discount);
            return true;
        }
        return false;
    }
    
    public static void edit_group_nr(String art_nr, String group_nr)
    {
        find_product_by_art_nr(art_nr).set_group_nr(group_nr);
    }
    
    public static void edit_discount(String art_nr, double discount)
    {
        find_product_by_art_nr(art_nr).set_discount(discount);
    }
    /**********************************************************************************DELETE PRODUCT**********************************************************************************************/
    
    /**
     * Method to delete a product by it's articule number
     */
    public static boolean delete_product(String art_nr)
    {
            return stock.remove(find_product_by_art_nr(art_nr));
    }
    
    /***********************************************************OTHER METHODS***************************************************************/
    
    public static boolean save_data()
    {
        return file.save_changes(stock);
    }
    
    public static boolean is_such_amount(String art_nr, String amount)
    {
        int current_amount = find_product_by_art_nr(art_nr).get_quantity();
        return(current_amount >= Integer.parseInt(amount));
    }
    
    public static boolean subtract_amount(String art_nr, String amount)
    {
        Product temp = find_product_by_art_nr(art_nr);
        temp.subtract_amount(Integer.parseInt(amount));
        return temp.needs_restocking();
    }
    
    public static boolean is_product_unfinished(String art_nr)
    {
        return find_product_by_art_nr(art_nr).is_unfinished();
    }
    
    public static boolean is_such_group_nr(String group_nr)
    {
        for (Product articule : stock)
        {
            if (articule.get_group_nr().equals(group_nr))
            {
                return true;
            }
        }
        return false;
    }
    
    public static boolean are_there_any_unfinished()
    {
        for(Product articule : stock)
        {
            if(articule.get_price() == 0)
            {
                return true;
            }
        }
        return false;
    }
    
    public static boolean do_any_require_restocking()
    {
        for(Product articule : stock)
        {
            if(articule.needs_restocking())
            {
                return true;
            }
        }
        return false;
    }
}
